﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BlackBird.Models;
using BlackBird.ControllerHelpers;

namespace BlackBird.DataAccess
{
    public static class BiJiaDanDataAccess
    {
		//我们要缓存比价单吗？
        private static List<BiJiaDanDM> bijiadanList = new List<BiJiaDanDM>();

        public static List<BiJiaDanDM> InitializeAllBijiadans() 
        {
            //if (bijiadanList.Count() > 0) return bijiadanList;

			List<BiJiaDanDM> retBiJiaDans = null;
            using (var dbContext = new blackbirdEntities())
            {
				var dbrets = dbContext.bijiandan.ToList();
				
				var dmrets = dbrets.Select<bijiandan, BiJiaDanDM>(p => BuildBiJiaDanDM(p));

				retBiJiaDans = dmrets.ToList();
            }
			bijiadanList = retBiJiaDans;
			return retBiJiaDans; 
        }

		/// <summary>
		/// Return all bijiadan below to the specified project
		/// </summary>
		/// <param name="projectId"></param>
		/// <returns></returns>
		public static List<BiJiaDanDM> GetAllBiJiaDans(string projectId)
		{
			var bijiadans = from b in bijiadanList
								 where b.ParentId == projectId
								 select b;

			return bijiadans.ToList();
		}


		/// <summary>
		/// 获得所有的比价单
		/// </summary>
		/// <returns></returns>
		public static List<BiJiaDanDM> GetAllBiJiaDans()
		{
			return bijiadanList.ToList();
		}

		/// <summary>
		/// Get BiJiaDan count under the specified projectId
		/// </summary>
		/// <param name="projectId"></param>
		/// <returns></returns>
		public static int GetAllBijiadansCount(int projectId)
		{
			using (var dbContext = new blackbirdEntities())
			{
				var bijiadans = from b in dbContext.bijiandan
								 where b.Project_idProject == projectId
								 select b;

				return bijiadans.Count();
			}
		}

		/// <summary>
		/// Get BiJiaDan count that created today
		/// </summary>
		/// <returns></returns>
		public static int GetTodayBijiadansCount()
		{
			using (var dbContext = new blackbirdEntities())
			{
				var bijiadans = from b in dbContext.bijiandan
								where b.Date == DateTime.Today
								select b;
				return bijiadans.Count();
			}
		}
        
        public static string CreatBiJiaDan(BiJiaDanDM bijiadanDm, Controller ctrl)
        {
            var userDb = AccountHelper.GetCurrentUser(ctrl);
            return CreatBiJiaDan(bijiadanDm, userDb);
        }

        public static string CreatBiJiaDan(BiJiaDanDM bijiadanDm, user userDb)
        {
            //在数据库中创建跟比价单有关的状态信息
            using (var dbContext = new blackbirdEntities())
            {
                int parentProjectId = Convert.ToInt32(bijiadanDm.ParentId);
                var projectDb = dbContext.project.First(p => p.idProject == parentProjectId);

                //Get SupportTypeStatus ID
                var statusID = CommonDataAccess.GetSupportTypeStatusId(bijiadanDm.Status);

				var bijiadanDb = bijiandan.Createbijiandan(0, userDb.idUser,statusID, projectDb.idProject);
                bijiadanDb.Name = bijiadanDm.Name;
				bijiadanDb.BianHao = bijiadanDm.BianHao;
                bijiadanDb.Date = bijiadanDm.Date;
				bijiadanDb.ProcessStep = bijiadanDm.CurrentStepNumber;

				bijiadanDb.PriceType = (int)bijiadanDm.PriceType;
				bijiadanDb.ContractType = (int)bijiadanDm.ContractType;
				bijiadanDb.PurchaseType = (int)bijiadanDm.PurchaseType;
				bijiadanDb.BusinessGroup = (int)bijiadanDm.BusinessGroup;
				bijiadanDb.BudgetDepartmentCheck = (int)bijiadanDm.BudgetDepartmentCheck;



                //save bijiadan to db
                dbContext.bijiandan.AddObject(bijiadanDb);
                dbContext.SaveChanges();

                //update the id of bijiadan dm
                bijiadanDm.Id = bijiadanDb.idBijiandan.ToString();
            }

            bijiadanList.Add(bijiadanDm);

            //保存比价单表格信息，比如有多少行多少列（这时候用户还没有输入产品的任何信息）
            SaveToDatabase(bijiadanDm);

            return bijiadanDm.Id;
        }

        public static void UpdateBiJiaDan(BiJiaDanDM dm)
        {
            var index = bijiadanList.FindIndex(p => p.Id == dm.Id);
            if (index < 0)
                bijiadanList.Add(dm);
            else
            {
                var findBijiadan = bijiadanList[index];

                //Name, Id, Parent, CreatUserName, Date之类的不可能变，不需要更新

                findBijiadan.Status = dm.Status;

                findBijiadan.PriceType = dm.PriceType;
                findBijiadan.ContractType = dm.ContractType;
                findBijiadan.PurchaseType = dm.PurchaseType;
                findBijiadan.BusinessGroup = dm.BusinessGroup;
                findBijiadan.BudgetDepartmentCheck = dm.BudgetDepartmentCheck;

                findBijiadan.table = dm.table;

                findBijiadan.TechComment_Project = dm.TechComment_Project;
                findBijiadan.TechComment_Center = dm.TechComment_Center;

				if (dm.AttachedFileList != null && dm.AttachedFileList.AttachedFiles.Count > 0)
					findBijiadan.AttachedFileList = dm.AttachedFileList;

                if (dm.Comments != null && dm.Comments.Count > 0)
                    findBijiadan.Comments = dm.Comments;
                findBijiadan.CurrentPostComment = dm.CurrentPostComment;
            }
        }

        /// <summary>
        /// Save Bijiadan to database
        /// </summary>
        /// <param name="dm"></param>
        public static void SaveToDatabase(BiJiaDanDM dm)
        {
            using (var dbContext = new blackbirdEntities())
            {
                int bijiadanDmId = Convert.ToInt32(dm.Id);
                var bijiadanDb = dbContext.bijiandan.First(p => p.idBijiandan == bijiadanDmId);
                //update status
                var bijiadanStatus = dm.Status.ToString();
                bijiadanDb.status = dbContext.status.First(p => p.StatusType == bijiadanStatus);
                bijiadanDb.ProcessStep = dm.CurrentStepNumber;

                //update properties from dropdownlists
                bijiadanDb.PriceType = (int)dm.PriceType;
                bijiadanDb.ContractType = (int)dm.ContractType;
                bijiadanDb.PurchaseType = (int)dm.PurchaseType;
                bijiadanDb.BusinessGroup = (int)dm.BusinessGroup;
                bijiadanDb.BudgetDepartmentCheck = (int)dm.BudgetDepartmentCheck;

                //厂商及技术备注
                bijiadanDb.TechComment_Project = dm.TechComment_Project;
                bijiadanDb.TechComment_Center = dm.TechComment_Center;

                for (int i = 1; i <= dm.table.Companies.Count(); i++)
                {
                    var supplierDm = dm.table.Companies[i - 1];
                    //1) create supplier
                    var suplierDb = SupplierDataAccess.SaveToDatabase(supplierDm);

                    //2) create bijiadan_supplier
                    var bijiadanSupplierDb = dbContext.bijiadan_supplier.FirstOrDefault(p =>
                        p.Bijiandan_idBijiandan == bijiadanDmId && p.Supplier_idSupplier == suplierDb.idSupplier);

                    if (bijiadanSupplierDb == null)
                    {
                        bijiadanSupplierDb = bijiadan_supplier.Createbijiadan_supplier(0,
                        suplierDb.idSupplier,
                        bijiadanDb.idBijiandan);
                        //1 based number
                        bijiadanSupplierDb.Order = i.ToString();
                        dbContext.bijiadan_supplier.AddObject(bijiadanSupplierDb);
                    }
                    
                    for (int j = 1; j <= dm.table.ProductRows.Count(); j++)
                    {
                        //3) Product
                        var OrderTableRowDM = dm.table.ProductRows[j - 1];
                        var productDb = ProductDataAccess.SaveToDatabase(OrderTableRowDM.Product);

                        //4) Supplier Product
                        var supplierProductDb = dbContext.supplier_product.FirstOrDefault(p =>
                            p.Supplier_idSupplier == suplierDb.idSupplier && p.Product_idProduct == productDb.idProduct);
                        if (supplierProductDb == null)
                        {
                            supplierProductDb = supplier_product.Createsupplier_product(0, suplierDb.idSupplier, productDb.idProduct);
                            dbContext.supplier_product.AddObject(supplierProductDb);
                        }

                        //5) Bijiadan Product
                        var bijiadanProductDb = dbContext.bijiadan_product.FirstOrDefault(p =>
                            p.Supplier_Product_idSupplier_Product == supplierProductDb.idSupplier_Product &&
                            p.Bijiadan_Supplier_idBijiadan_Supplier == bijiadanSupplierDb.idBijiadan_Supplier);

                        if (bijiadanProductDb == null)
                        {
                            bijiadanProductDb = bijiadan_product.Createbijiadan_product(0,
                                supplierProductDb.idSupplier_Product,
                                bijiadanSupplierDb.idBijiadan_Supplier);

                            bijiadanProductDb.RowOrder = j.ToString();
                            dbContext.bijiadan_product.AddObject(bijiadanProductDb);
                        }

                        //数量
                        bijiadanProductDb.Count = OrderTableRowDM.Product.Count;

                        //价格
                        var supplierPriceDm = OrderTableRowDM.SupplierDeclarePrices[i-1];
                        bijiadanProductDb.Price = supplierPriceDm.DeclarePrice.ToString();
                        bijiadanProductDb.ShenhePrice = supplierPriceDm.VerifyPrice.ToString();

                        //todo reference price
                        if (i == 1 && j == 1)
                        { 
                            
                        }
                        
                        dbContext.SaveChanges();
                    }

                    dbContext.SaveChanges();
                }

                dbContext.SaveChanges();
            }
        }

        /// <summary>
        /// Only save Bijiadan Status (guidang, zuofei etc.)
        /// </summary>
        /// <param name="dm"></param>
        public static void SaveBijiadanSatusToDatabase(BiJiaDanDM dm)
        {
            using (var dbContext = new blackbirdEntities())
            {
                int bijiadanDmId = Convert.ToInt32(dm.Id);
                var bijiadanDb = dbContext.bijiandan.First(p => p.idBijiandan == bijiadanDmId);

                var bijiadanStatus = dm.Status.ToString();
                bijiadanDb.status = dbContext.status.First(p => p.StatusType == bijiadanStatus);

                dbContext.SaveChanges();
            }
        }

		/// <summary>
		/// Build Bijiadan from database
		/// </summary>
		/// <param name="bijiadanDb"></param>
		/// <returns></returns>
		public static BiJiaDanDM BuildBiJiaDanDM(bijiandan bijiadanDb)		
        {
			if (bijiadanDb == null) return null;

			//0) read bijidadan information
			BiJiaDanDM bijiadanDm = new BiJiaDanDM()
			{
				Id = bijiadanDb.idBijiandan.ToString(),
				Name = bijiadanDb.Name,
				BianHao = bijiadanDb.BianHao,
				ParentId = bijiadanDb.project.idProject.ToString(),
				CreateUser_idUser = bijiadanDb.User_idUser,
				Date = (DateTime)bijiadanDb.Date,
                CreateUserName = bijiadanDb.user.DisplayName,
				Status = CommonDataAccess.GetSupportTypeStatusById((int)bijiadanDb.status.idStatus),
                CurrentStepNumber = (int)bijiadanDb.ProcessStep,

				//Throw exception
                PriceType = (PriceType)(bijiadanDb.PriceType),
                ContractType = (ContractType)(bijiadanDb.ContractType),
                PurchaseType = (PurchaseType)(bijiadanDb.PurchaseType),
                BusinessGroup = (BusinessGroup)(bijiadanDb.BusinessGroup),
                BudgetDepartmentCheck = (BudgetDepartmentCheck)(bijiadanDb.BudgetDepartmentCheck),

				TechComment_Project = bijiadanDb.TechComment_Project,
				TechComment_Center = bijiadanDb.TechComment_Center
			};

			//build bijiadan table
			BiJiaDanTableDM tableDm = new BiJiaDanTableDM();
			bijiadanDm.table = tableDm;
			tableDm.Companies = new List<SupplierDM>();
			tableDm.ProductRows = new List<OrderTableRowDM>();

			//1) read supplier from 1 to n
			int supplierCount = bijiadanDb.bijiadan_supplier.Count;
			for (int i = 1; i <= supplierCount; i++)
			{
				var bijidadan_supplier_db = bijiadanDb.bijiadan_supplier.FirstOrDefault(p => p.Order == i.ToString());
				SupplierDM supplier = SupplierDataAccess.BuildSupplierDM(bijidadan_supplier_db.supplier);
				tableDm.Companies.Add(supplier);

				//2) build product rows
				int productCount = bijidadan_supplier_db.bijiadan_product.Count;
				for (int j = 1; j <= productCount; j++)
				{
					var bijiadan_product_db = bijidadan_supplier_db.bijiadan_product.FirstOrDefault(p => p.RowOrder == j.ToString());

					if (bijiadan_product_db != null)
					{
						var supplier_product = bijiadan_product_db.supplier_product;

						//3) build product
						//products only need to initialize once
						if (i == 1)
						{
							var productRow = new OrderTableRowDM();
							productRow.XuHao = j;
							productRow.Product = ProductDataAccess.BuildProductDM(supplier_product.product);
							
                            //设置产品数量
                            productRow.Product.Count = bijiadan_product_db.Count;
                            
                            tableDm.ProductRows.Add(productRow);
						}

						//4) set prices
						var productRowDm = tableDm.ProductRows[j - 1];
						if (productRowDm.SupplierDeclarePrices == null)
							productRowDm.SupplierDeclarePrices = new List<SupplierDeclarePriceDM>();

                        var supplierPrices = new SupplierDeclarePriceDM();
                        if (!string.IsNullOrEmpty(bijiadan_product_db.Price))
							    supplierPrices.DeclarePrice = Convert.ToDouble(bijiadan_product_db.Price);
                        if (!string.IsNullOrEmpty(bijiadan_product_db.ShenhePrice))
                            supplierPrices.VerifyPrice = Convert.ToDouble(bijiadan_product_db.ShenhePrice);
						productRowDm.SupplierDeclarePrices.Add(supplierPrices);
					}
				}
			}

            //审核记录
            bijiadanDm.Comments = ShenheDataAccess.GetBijiadanShenhe(bijiadanDm.Id);

			return bijiadanDm;
		}

        public static BiJiaDanDM GetBiJiaDan(string ID)
        {
            return bijiadanList.SingleOrDefault(p => p.Id == ID);
        }

        public static BiJiaDanTableDM CreateDefaultTable(int nCompayCount, int nProductCount)
        {
            BiJiaDanTableDM oT = new BiJiaDanTableDM();
            oT.Companies = new List<SupplierDM>();
            for (int index = 0; index < nCompayCount; index++)
            {
                var supplier = new SupplierDM()
                {
                    Name = "",
                    ContactorInfo = new Contactor
                    {
                        RealName = "",
                        Tel = ""
                    }
                };
                oT.Companies.Add(supplier);

                oT.ReferenceCompany = new SupplierDM()
                {
                    Name = "",
                    ContactorInfo = new Contactor
                    {
                        RealName = "",
                        Tel = ""
                    }
                };

                SupplierDataAccess.AddSupplier(supplier);
            }
            oT.ProductRows = new List<OrderTableRowDM>();

            for (int index = 0; index < nProductCount; index++)
            {
                var productRow = new OrderTableRowDM();
                productRow.XuHao = index + 1;

                productRow.Product = new ProductDM()
                {
                    Name = "",
                    Unit = ""
                };

                productRow.ReferencePrice = null;

                ProductDataAccess.AddProduct(productRow.Product);

                productRow.SupplierDeclarePrices = new List<SupplierDeclarePriceDM>();

                for (int y = 0; y < nCompayCount; y++)
                {
                    productRow.SupplierDeclarePrices.Add(new SupplierDeclarePriceDM() {  });
                }
                oT.ProductRows.Add(productRow);
            }

            return oT;
        }
    }
}
